﻿#region License
/* Copyright (C) 2009 Tim Coulter
 * 
 * This file is part of ExtremeML.
 * 
 * ExtremeML is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public
 * License, as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
*/
#endregion

using DocumentFormat.OpenXml.Packaging;
using ExtremeML.Packaging;

namespace ExtremeML.Core
{
	/// <summary>
	/// Serves as the base class for classes that wrap instances of <see cref="OpenXmlPart"/>.
	/// </summary>
	/// <typeparam name="TWrapped">A type that derives from <see cref="OpenXmlPart"/>.</typeparam>
	public abstract class PartWrapper<TWrapped> : ItemWrapper<TWrapped>, IPartWrapper
		where TWrapped : OpenXmlPart
	{
		#region Housekeeping

		/// <summary>
		/// Initializes a new instance of the <see cref="PartWrapper{TWrapped}"/> class.
		/// </summary>
		/// <param name="wrapped">An <see cref="OpenXmlPart"/> from which to populate this instance.</param>
		/// <param name="parent">An <see cref="IContentWrapper"/> that represents the parent wrapper instance.</param>
		/// <param name="package">An <see cref="IContentWrapper"/> that represents the package wrapper instance.</param>
		protected PartWrapper(
			TWrapped wrapped,
			IContentWrapper parent,
			IContentWrapper package)
			: base(wrapped, parent, package)
		{
		}

		#endregion
		#region Properties

		/// <summary>
		/// Gets or sets whether this instance has been removed from the wrapper hierarchy.
		/// </summary>
		private bool IsRemoved { get; set; }

		/// <summary>
		/// Gets the collection of <see cref="HyperlinkRelationship"/> associated with this the wrapped worksheet part.
		/// </summary>
		internal HyperlinkRelationshipManager Hyperlinks { get; private set; }

		#endregion
		#region Overrides

		/// <summary>
		/// When overridden in a derived generated partial class, populates the derived instance using default values.
		/// </summary>
		protected override void OnInitializing()
		{
			Wrapped = null;
		}

		/// <summary>
		/// When overridden in a derived generated partial class, declares custom wrapper population functionality.
		/// </summary>
		protected override void OnDecomposing()
		{
			Hyperlinks = new HyperlinkRelationshipManager(Wrapped);
		}

		#endregion
		#region Life-Cycle Methods


		#endregion
		#region Content Management Methods

		/// <summary>
		/// Deletes the instance, subject to its context within the wrapper hierarchy.
		/// </summary>
		internal override void Remove()
		{
			if (IsRemoved) return;

			OnCustomRemoving();

			if (typeof(IWrapperCollection).IsAssignableFrom(Parent.GetType()))
			{
				// Delete the element wrapper from its parent collection
				((IWrapperCollection)Parent).Remove(this);
			}

			OnCustomRemoved();

			IsRemoved = true;
		}

		#endregion

		/// <summary>
		/// Returns a value that represents an custom override of the default part content.
		/// Derived classes may use the "new" keyword to hide this method and implement a
		/// replacement method that returns default content appropriate to their context.
		/// </summary>
		/// <param name="container">An <see cref="OpenXmlPartContainer"/> that will contain the new part.</param>
        /// <param name="args">A parameter array of <see cref="object"/> containing member initialization arguments.</param>
        /// <returns>A new instance of a class that derives from <see cref="OpenXmlPart"/>.</returns>
		internal static TWrapped CreateCustomDefaultPart(
			OpenXmlPartContainer container,
            params object[] args)
		{
			return null;
		}
	}
}
